#include <kutils.h>
#include "task.h"
#include "display.h"
#include "syscall.h"

void task_exit_handler(syscall_regs_t *r);
void task_level_handler(syscall_regs_t *r);
void task_exec_handler(syscall_regs_t *r);
void task_sleep_handler(syscall_regs_t *r);
void task_cpu_handler(syscall_regs_t *r);

extern volatile u32int task_working;
extern u32int cpu_usage;
extern task_t* current_task;

void task_exit_handler(syscall_regs_t *r)
{
	if(!r)
		return;
	task_exit();//this will terminate the current task so there is no need to return any values
}

void task_level_handler(syscall_regs_t *r)
{
	s32int success = task_level((s8int)r->arg1);
	if(success)
		r->res1 = r->arg1;
	else
		r->res1 = (u32int)current_task->level;
	r->success = (u32int)success;
}

void task_exec_handler(syscall_regs_t *r)
{
	r->success = (u32int)task_exec((s8int*)r->arg1);
}

void task_sleep_handler(syscall_regs_t *r)
{
	//TODO: Call the scheduler to change tasks.
	// For now, just busy wait with hlt.
	u32int i = 0;
	for(i = r->arg1; i > 0; i--)
	{
		task_working = 0;
		__asm__ __volatile__("hlt");
	}
	r->success = 1;
	task_working = 1;
}

void task_cpu_handler(syscall_regs_t *r)
{
	r->res1 = cpu_usage;
	r->success = 1;
}

void init_task_interface(void)
{
	install_syscall(SYS_EXIT, task_exit_handler);
	install_syscall(SYS_LEVEL, task_level_handler);
	install_syscall(SYS_EXEC, task_exec_handler);
	install_syscall(SYS_SLEEP, task_sleep_handler);
	install_syscall(SYS_CPU_INFO, task_cpu_handler);
}
